package com.sparrow.common.aoi.domain;

import com.sparrow.common.aoi.impl.crosslinked.CrossLinkedAOISystem;
import com.sparrow.common.aoi.util.MapUtil;
import com.sparrow.common.util.FileUtil;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 地图数据
 */
public class MapData {
    /**
     * 宽度有多少个格子
     */
    private int width;
    /**
     * 九宫格区域的宽有多少个格子
     */
    public int areaWidth;
    /**
     * 九宫格区域的高有多少个格子
     */
    public int areaHeight;
    /**
     * 高度有多少个格子
     */
    private int height;
    /**
     * 九宫格区域的宽有多少个格子
     */
    private int areaCols;
    /**
     * 九宫格区域的高有多少个格子
     */
    private int areaRows;

    public CrossLinkedAOISystem.CrossLinkedNode xHead = null;
    public CrossLinkedAOISystem.CrossLinkedNode yHead = null;
    private byte[][] walkable;

    public MapData(int width, int height, int AREA_WIDTH, int AREA_HEIGHT) {
        this.width = width;
        this.height = height;
        this.areaWidth = AREA_WIDTH;
        this.areaHeight = AREA_HEIGHT;
        // 计算区域数量（向上取整）
        int areaCols = (width + AREA_WIDTH - 1) / AREA_WIDTH;
        int areaRows = (height + AREA_HEIGHT - 1) / AREA_HEIGHT; // ⚠️ 这里原来写成 width，应该用 height
        this.areaCols = areaCols;
        this.areaRows = areaRows;
        // 初始化 walkable 数组，默认全部可走（true）
        this.walkable = new byte[height][width]; // ✅ 第一维=行(y)，第二维=列(x)
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                this.walkable[y][x] = 0;
            }
        }
    }

    public byte[][] getWalkable() {
        return walkable;
    }

    public int getAreaWidth() {
        return areaWidth;
    }

    public int getAreaHeight() {
        return areaHeight;
    }

    public boolean isWalkable(int x, int y) {
        if (x < 0 || x >= width || y < 0 || y >= height) return false;
        return walkable[y][x] == 0; // ✅ 行在前，列在后
    }

    public void setWalkable(int x, int z, byte value) {
        walkable[z][x] = value;
    }

    public int getAreaCols() {
        return areaCols;
    }

    public void setAreaCols(int areaCols) {
        this.areaCols = areaCols;
    }

    public int getAreaRows() {
        return areaRows;
    }

    public void setAreaRows(int areaRows) {
        this.areaRows = areaRows;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public CrossLinkedAOISystem.CrossLinkedNode getXHead() {
        return xHead;
    }

    public CrossLinkedAOISystem.CrossLinkedNode getYHead() {
        return yHead;
    }

    public void setXHead(CrossLinkedAOISystem.CrossLinkedNode xHead) {
        this.xHead = xHead;
    }

    public void setYHead(CrossLinkedAOISystem.CrossLinkedNode yHead) {
        this.yHead = yHead;
    }

    // 解析二进制文件
    public static MapData loadFromFile(String mapDataName, int areaWidth)  {
        try {
            File file = FileUtil.getFile("config/mapData/" + mapDataName + ".bytes");
            try (DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)))) {
                int width = readIntLE(dis);
                int height = readIntLE(dis);
                MapData map = new MapData(width, height, areaWidth, areaWidth);

                for (int z = 0; z < height; z++) { //y
                    for (int x = 0; x < width; x++) { //x
                        byte b = dis.readByte();
                        byte v = (byte) (b == 1 ? 0 : 1);
                        map.setWalkable(x, z, v);
                    }
                }
                return map;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 小端序读取 4 字节 int
     */
    private static int readIntLE(DataInputStream dis) throws IOException {
        int ch1 = dis.readUnsignedByte();
        int ch2 = dis.readUnsignedByte();
        int ch3 = dis.readUnsignedByte();
        int ch4 = dis.readUnsignedByte();
        return (ch1) | (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
    }

    /**
     * 根据格子数据生成 MapData（带区域划分）
     */
    public static MapData create(int width, int height) {
        MapData mapData = new MapData(width, height, MapUtil.AREA_WIDTH, MapUtil.AREA_HEIGHT);
        return mapData;
    }


}
